package com.foreveross.crawl.adapter.sub.impl20140402.v3;

import java.net.URLDecoder;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.cookie.Cookie;
import org.apache.http.impl.client.AbstractHttpClient;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

import com.foreveross.crawl.adapter.AbstractAdapter;
import com.foreveross.crawl.adapter.PlaneInfoEntityBuilder;
import com.foreveross.crawl.adapter.sub.impl20140402.v3.qunar.PriceCollect;
import com.foreveross.crawl.adapter.sub.impl20140402.v3.qunar.QunarDomesticOneWay;
import com.foreveross.crawl.adapter.sub.impl20140402.v3.qunar.QunarInterRound;
import com.foreveross.crawl.common.PlaneInfoCommon;
import com.foreveross.crawl.common.QueryJavaScriptEngine;
import com.foreveross.crawl.common.exception.self.UnableParseRouteTypeException;
import com.foreveross.crawl.common.util.RandomBrowserVersion;
import com.foreveross.crawl.common.util.RegHtmlUtil;
import com.foreveross.crawl.domain.airfreight.AbstractPlaneInfoEntity;
import com.foreveross.crawl.domain.airfreight.AgentEntity;
import com.foreveross.crawl.domain.airfreight.CabinEntity;
import com.foreveross.crawl.domain.airfreight.StopOverEntity;
import com.foreveross.crawl.domain.airfreight.TransitEntity;
import com.foreveross.crawl.domain.airfreight.doub.DoublePlaneInfoEntity;
import com.foreveross.crawl.domain.airfreight.doub.ReturnAgentEntity;
import com.foreveross.crawl.domain.airfreight.doub.ReturnDoublePlaneInfoEntity;
import com.foreveross.crawl.domain.airfreight.doub.ReturnStopOverEntity;
import com.foreveross.crawl.domain.airfreight.doub.ReturnTransitEntity;
import com.foreveross.crawl.domain.airfreight.single.SinglePlaneInfoEntity;
import com.foreveross.crawl.enums.RouteTypeEnum;
import com.foreveross.taskservice.common.bean.TaskModel;
import com.gargoylesoftware.htmlunit.WebClient;
import com.gargoylesoftware.htmlunit.html.HtmlElement;
import com.gargoylesoftware.htmlunit.html.HtmlForm;
import com.gargoylesoftware.htmlunit.html.HtmlInput;
import com.gargoylesoftware.htmlunit.html.HtmlPage;
import com.gargoylesoftware.htmlunit.html.HtmlRadioButtonInput;

/**
 * 新的去哪儿适配器 使用新的模型 优先国际数据解析 优先往返 国内单程修复完成 目前需要测试，很不稳定
 * 
 * @author guokenye
 * 
 */
public class QunarAdapter extends AbstractAdapter {
	private static final List<String> airCompany = new ArrayList<String>();
	static {
		airCompany.add("CZ");
		airCompany.add("CA");
		airCompany.add("HU");
		airCompany.add("SC");
		airCompany.add("MU");
		airCompany.add("ZH");
		airCompany.add("MF");
		airCompany.add("3U");
		airCompany.add("JD");
		airCompany.add("KY");
		airCompany.add("GS");
		airCompany.add("8L");
		airCompany.add("PN");
		airCompany.add("HO");
		airCompany.add("BK");
		airCompany.add("DZ");
	}
	
	/**
	 * 当国内航班抓取联程时尝试抓取次数
	 */
	private static int crawlMoreTry=3;

	private static JSONObject agentInfos = new JSONObject();
	
	// 往返获取代理商开关（true 获取代理信息，false不获取代理信息）
	private static boolean returnFlag = false;

	private final static SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm");
	
	private static final int normalFlag = 0;
	private static final int moreFlag = 1;
	
	private int fetchFlag = normalFlag;

	public QunarAdapter(TaskModel taskQueue) {
		super(taskQueue);
	}

	@Override
	public Object fetch(String url) throws Exception {

		switch (super.getRouteType()) {
		case DOMESTIC_ONEWAYTRIP:
			//return fetchDomeOneWay();
			//return newFetchDomeOneWay();//新的国内方法
			return new QunarDomesticOneWay(this,taskQueue).fetch();
		case INTERNATIONAL_ONEWAY:
			return fetchInterOneway();
		case INTERNATIONAL_ROUND:
			return new QunarInterRound(this,taskQueue).fetch();
			//return fetchInterRound();
		default:
			throw new UnableParseRouteTypeException(taskQueue, super.getRouteType().getName());
		}
	}

	/**
	 * ping一下首页，设置数据
	 * 
	 * @param h
	 * @param g
	 * @throws Exception
	 */

	public void setCookiesToMethodByPing(String setUrl, HttpClient h, HttpGet g) throws Exception {
		List<Cookie> cookies = null;
		StringBuilder sbuilder = new StringBuilder();
		HttpGet temp = null;
		try {
			/* h.getParams().setParameter(ClientPNames.COOKIE_POLICY,CookiePolicy.BEST_MATCH); */
			g.setHeader("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
			g.setHeader("Accept-Language", "zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3");
			g.setHeader("Host", "flight.qunar.com");
			g.setHeader("Connection", "keep-alive");
			g.setHeader("User-Agent", RandomBrowserVersion.getBV().getUserAgent());
			if (setUrl != null) {
				g.setHeader("Referer", setUrl);
				temp = new HttpGet(setUrl);
				excuteRequest(h, temp, false);
			}
			cookies = ((AbstractHttpClient) h).getCookieStore().getCookies();
			if (cookies != null) {
				for (Cookie c : cookies) {
					sbuilder.append(c.getName()).append("=").append(c.getValue()).append(";");
				}
				g.setHeader("Cookie", sbuilder.toString());
			}
		} finally {
			sbuilder = null;
			cookies = null;
			/*
			 * if (temp != null) { temp.releaseConnection(); }
			 */
		}

	}
	
	/**
	 * 去哪儿国内用  com.gargoylesoftware.htmlunit.WebClient 抓取
	 * @return
	 * @throws Exception
	 */
	private Object newFetchDomeOneWay()throws Exception {
		String url="http://flight.qunar.com/";
		String page;
		HtmlPage queryPage;
		HtmlPage dataPage;
		WebClient clent=null;
		try {
			clent=super.getWebClient();
			clent.getOptions().setCssEnabled(false);
			clent.getOptions().setTimeout(10*1000);
			
			clent.setJavaScriptEngine(new QueryJavaScriptEngine(clent));
			queryPage=clent.getPage(url);
			clent.waitForBackgroundJavaScript(1000*2);
			HtmlForm form=(HtmlForm) queryPage.getElementById("dfsForm");
			
			HtmlRadioButtonInput searchType=form.getInputByValue("OnewayFlight");
			searchType.click();
			
			
			HtmlInput fromCity=form.getInputByName("fromCity");
			fromCity.setValueAttribute(getCity(this.taskQueue.getFromCityName()));
			
			HtmlInput toCity=form.getInputByName("toCity");
			toCity.setValueAttribute(getCity(this.taskQueue.getToCityName()));
			
			HtmlInput fromDate=form.getInputByName("fromDate");
			fromDate.setValueAttribute(taskQueue.getFlightDate());
			
			Iterable<HtmlElement> list =form.getElementsByTagName("button");
			HtmlElement button=list.iterator().next();
			
			dataPage=button.click();
			button=null;
//			//等待模拟浏览器载入数据
//			Thread.sleep(1000*15);
			clent.waitForBackgroundJavaScript(1000*10);
			//每页显示60条
//			HtmlElement p=(HtmlElement) dataPage.getHtmlElementById("ulListXI2").getLastChild();
//			if(null!=p)
//				dataPage=p.click();
//			p=null;
//	//		获得第一条数据的代理信息
//			DomElement element=	dataPage.getElementById("hdivResultPanel");
//			DomElement div=element.getFirstElementChild();
//			String id=div.getId();
//			if(id!=null && id.startsWith("itemBarXI")){
//				id="openwrapperbtnXI"+id.substring(9);
//				HtmlAnchor a=(HtmlAnchor) dataPage.getElementById(id);
//				dataPage=a.click();
//				clent.waitForBackgroundJavaScript(1000*5);
//			}
		
			page=dataPage.asXml();
			clent.closeAllWindows();
			clent=null;
			super.appendPageContents(page);//设置源网页数据
			return page;
		} finally {
				page = null;
				if(null!=clent)
					clent.closeAllWindows();
				queryPage=null;
				dataPage=null;
			
			}
	}

	/**
	 * 进入国内单程
	 * 
	 * @return
	 * @throws Exception
	 */
	private Object fetchDomeOneWay() throws Exception {

		HttpClient h = null;
		HttpGet g = null;
		Map<String, String> p = new HashMap<String, String>();
		String page;
		JSONObject j;
		try {
			h = getHttpClient();

			int token=(int) (Math.random()*100000);
			p.put("_token", token+"");
			p.put("from", "qunarindex");
			p.put("http://www.travelco.com/searchDepartureAirport", getCity(this.taskQueue.getFromCityName()));
			p.put("http://www.travelco.com/searchArrivalAirport", getCity(this.taskQueue.getToCityName()));
			p.put("http://www.travelco.com/searchDepartureTime", taskQueue.getFlightDate());
			p.put("http://www.travelco.com/searchReturnTime", taskQueue.getFlightDate());
			p.put("locale", "zh");
			p.put("mergeFlag", "0");
			p.put("nextNDays", "0");
			p.put("prePay", "true");
			p.put("searchLangs", "zh");
			p.put("searchType", "OneWayFlight");
			p.put("tags", "1");
			p.put("www", "true");
			p.put("xd", "f" + System.currentTimeMillis());
			p.put("wyf", "");
			
//			p.put("_token", "72642");
//			p.put("from", "fi_dom_search");
//			p.put("http://www.travelco.com/searchDepartureAirport", this.taskQueue.getFromCityName());
//			p.put("http://www.travelco.com/searchArrivalAirport", this.taskQueue.getToCityName());
//			p.put("http://www.travelco.com/searchDepartureTime", taskQueue.getFlightDate());
//			p.put("http://www.travelco.com/searchReturnTime", taskQueue.getFlightDate());
//			p.put("locale", "zh");
//			p.put("mergeFlag", "0");
//			p.put("nextNDays", "0");
//			p.put("searchLangs", "zh");
//			p.put("searchType", "OneWayFlight");
//			p.put("tags", "1");
//			p.put("xd", "ccc" + System.currentTimeMillis());
			g = super.getBaseGet("http://flight.qunar.com/twell/longwell", p);
			setCookiesToMethodByPing("http://flight.qunar.com/", h, g);

			page = excuteRequest(h, g, true);
			
			super.appendPageContents(page);//设置源网页数据
			j = JSONObject.fromObject(page.trim().replaceAll("^\\(|\\)$", ""));
			this.validateFetch(j);
		} finally {
			page = null;
			if (g != null) {
				g.releaseConnection();
				g = null;
			}
			h = null;
		}
		return j;

	}

	/**
	 * 
	 * 进入国际单程 返回json
	 * 
	 * @return
	 * @throws Exception
	 */
	private Object fetchInterOneway() throws Exception {

		HttpClient h = null;
		HttpGet g = null;
		Map<String, String> p = new HashMap<String, String>();
		String page;
		JSONObject j;
		try {
			h = getHttpClient();
			p.put("_token", "");
			p.put("from", "fi_ont_search");
			p.put("http://www.travelco.com/searchDepartureAirport", this.taskQueue.getFromCity());
			p.put("http://www.travelco.com/searchArrivalAirport", this.taskQueue.getToCity());
			p.put("http://www.travelco.com/searchDepartureTime", taskQueue.getFlightDate());
			p.put("http://www.travelco.com/searchReturnTime", taskQueue.getFlightDate());
			p.put("locale", "zh");
			p.put("mergeFlag", "0");
			p.put("nextNDays", "0");

			p.put("prePay", "true");
			p.put("searchLangs", "zh");
			p.put("searchType", "OneWayFlight");
			p.put("split", "true");
			p.put("www", "true");
			p.put("xd", "lw" + System.currentTimeMillis());
			g = super.getBaseGet("http://flight.qunar.com/twelli/longwell?", p);
			setCookiesToMethodByPing("http://flight.qunar.com", h, g);
			try {
				page = excuteRequest(h, g, true);
				super.appendPageContents(page);//设置源网页数据
				j = JSONObject.fromObject(page.trim().replaceAll("^\\(|\\)$", ""));
			} catch (Exception e) {
				page = excuteRequest(h, g, true);
				super.appendPageContents(page);//设置源网页数据
				j = JSONObject.fromObject(page.trim().replaceAll("^\\(|\\)$", ""));
			}

		} finally {
			page = null;
			if (g != null) {
				g.releaseConnection();
				g = null;
			}
			h = null;
		}
		return j;

	}

	

	@Override
	public boolean validateFetch(Object fetchObject) throws Exception {
		//国际往返的不用验证了
		if(getRouteType() == RouteTypeEnum.INTERNATIONAL_ROUND){
			return true;
		}
	
//		if(getRouteType()==RouteTypeEnum.DOMESTIC_ONEWAYTRIP){
//			return true;
//		}
		JSONObject j;
		try {
			if(fetchObject == null){
				return false;
			}
			j = (JSONObject) fetchObject;
			if (j.get("isLimit") != null && j.getBoolean("isLimit")) {
				throw new Exception("去哪儿获取数据错误 isLimit=" + j.get("isLimit"));
			}
			if (j.get("errorInfo") != null) {
				String msg = j.getString("errorInfo").replaceAll("\\[", "").replaceAll("\\]", "").replaceAll("\\s", "");
				if (msg.matches(".*INVALID_AIRLINE.*")) {
					throw new Exception();
				}
				if (!"".equals(msg)) {
					throw new Exception("去哪儿获取数据错误" + msg);
				}
			}
//			if (super.getRouteType() == RouteTypeEnum.DOMESTIC_ONEWAYTRIP || super.getRouteType() == RouteTypeEnum.INTERNATIONAL_ONEWAY) {
//				if (j.getJSONObject("oneway_data").get("flightInfo") == null || j.getJSONObject("oneway_data").getJSONObject("flightInfo").isEmpty()) {
//					throw new Exception("去哪儿数据不全");
//				}
//			}

		} finally {
			j = null;
		}
		return true;
	}

	@Override
	public List<Object> paraseToVo(Object obj) throws Exception {
		/**
		 * tagPriceData 留学生 priceData 推荐网站 priceInfo 最低票价
		 */
		switch (super.getRouteType()) {
		case DOMESTIC_ONEWAYTRIP:
			return paraseDomeOneWay(obj);
			//return newParaseDomeOneWay(obj);
			//return (List<Object>)obj;
		case INTERNATIONAL_ONEWAY:
			return paraseInterOneWay(obj);
		case INTERNATIONAL_ROUND:
			validateFetch(obj);
			return (List<Object>)obj;
			//return parseInterRound(obj);
		}
		return null;
	}
	
	public List<Object> newParaseDomeOneWay(Object obj) throws Exception {
		List<SinglePlaneInfoEntity> result = new ArrayList<SinglePlaneInfoEntity>();
		Document doc = Jsoup.parse(obj.toString());
		Element divElem=doc.getElementById("hdivResultPanel");
		Elements flights=divElem.getElementsByClass("avt_column");
		try {
				for(Element flight:flights){
					try {
						if(null!=flight.getElementsByClass("avt_column_1st") && !flight.getElementsByClass("avt_column_1st").isEmpty())
						{
							SinglePlaneInfoEntity plane=this.paraseTraint(flight);
							if(null!=plane)
								result.add(plane);
							continue;
						}
						String actuallyFlightNo=null;
						String[] a_name=flight.getElementsByClass("a_name").get(0).text().split(" ");
						String carrierName=a_name[0];
						String flightNo=a_name[1];
						String carrierKey=flightNo.substring(0, 2);
						String flightType=flight.getElementsByClass("a_model").get(0).text();
						if(flightType.indexOf("共享")>1){
							flightType=flightType.replace(" ", "").replace("共享", "");
							String title=flight.getElementsByClass("lnk_a").get(0).attr("title");
							actuallyFlightNo=title.replaceAll("[\u4e00-\u9fa5]", "").replace("：", "");
						}
						String startTime=flight.getElementsByClass("a_tm_dep").get(0).text();
						String endTime=flight.getElementsByClass("a_tm_arv").get(0).text();
						Element prc=flight.getElementsByClass("prc").get(0);
						String price=this.changToPrice(prc);
						
						SinglePlaneInfoEntity planeInfo=PlaneInfoEntityBuilder.buildPlaneInfo(taskQueue, carrierKey, carrierName, 
								carrierName, startTime, endTime, flightNo, price, null, null, flightType,
								null, null, null, null, SinglePlaneInfoEntity.class);
						//开始时间大于结束时间 就+1
						if(planeInfo.getStartTime().compareTo(planeInfo.getEndTime())>0){
							Calendar c=Calendar.getInstance();
							c.setTime(planeInfo.getEndTime());
							c.add(Calendar.DAY_OF_MONTH, 1);
							planeInfo.setEndTime(c.getTime());
						}
						planeInfo.setActuallyFlightNo(actuallyFlightNo);
						CabinEntity cabinEntity =new CabinEntity();
						cabinEntity.setPrice(null==price?null:Double.parseDouble(price));
						planeInfo.getCabins().add(cabinEntity);
						
						Elements agents=flight.getElementsByClass("qvt_column");
						if(null!=agents && agents.size()>0){
							for(Element el:agents){
								try {
									String name=el.getElementsByClass("t_name").get(0).text();
									Element prcEm=el.getElementsByClass("prc").get(el.getElementsByClass("prc").size()-1);
									String agentPrice=this.changToPrice(prcEm);
									AgentEntity agent=new AgentEntity();
									agent.setName(name);
									agent.setPrice(Double.parseDouble(agentPrice));
									planeInfo.getAgents().add(agent);
								} catch (Exception e) {
									e.printStackTrace();
								}
							}
							agents=null;
						}
						
						
						try {
							Elements a_rtlst=flight.getElementsByClass("a_rtlst");
							if(a_rtlst!=null && !a_rtlst.isEmpty()){
								String agentName=a_rtlst.get(0).text();
								String agentPrice=a_rtlst.get(1).text().split(" ")[1];
								AgentEntity agent=new AgentEntity();
								agent.setName(agentName);
								agent.setPrice(Double.parseDouble(agentPrice));
								planeInfo.getAgents().add(agent);
							}
						} catch (Exception e) {
							e.printStackTrace();
						}
						result.add(planeInfo);
					} catch (Exception e) {
						e.printStackTrace();
					}
					
				}
		}finally{
			doc=null;
			divElem=null;
			flights=null;
			obj=null;
		}
//		Element a=flights.get(0).getElementsByClass("a_booking").get(0).getElementsByTag("a").get(0);
//		String id=a.attr("id");
//		fethMoreAgent(id);
		try{
			PlaneInfoEntityBuilder.buildLimitPrice(result);
			}catch(Exception e){
				logger.info("国内单程排序错误，请检查数据");
				logger.info(e);
				try{
					logger.info(result);
				}catch(Exception e1){
					logger.info("打印数据出错");
				}
			}
		
		return Arrays.asList(result.toArray());
		
	}
	
	/**
	 * 解析国内中转
	 * @param flight
	 * @return
	 * @throws Exception 
	 */
	private SinglePlaneInfoEntity paraseTraint(Element flight) throws Exception {
		Element traint_st=flight.getElementsByClass("avt_column_1st").first();
		Elements traints=flight.getElementsByClass("avt_column_2nd");
		if(null==traints || traints.isEmpty())
			return null;
		TransitEntity start =this.paraseTraintByElement(traint_st);
		TransitEntity end=this.paraseTraintByElement(traints.get(0));
		Element prc=flight.getElementsByClass("prc").get(0);
		String price=this.changToPrice(prc);
		SinglePlaneInfoEntity planeInfo=PlaneInfoEntityBuilder.buildPlaneInfo(taskQueue, start.getCarrierKey(), start.getCarrierName(), 
				start.getCarrierFullName(), null, null, start.getFlightNo(), price, null, null, start.getFlightType(),
				null, null, null, null, SinglePlaneInfoEntity.class);
		planeInfo.setStartTime(start.getStartTime());
		planeInfo.setEndTime(end.getEndTime());
		planeInfo.getTransits().add(start);
		planeInfo.getTransits().add(end);
		CabinEntity cabinEntity =new CabinEntity();
		cabinEntity.setPrice(null==price?null:Double.parseDouble(price));
		planeInfo.getCabins().add(cabinEntity);
		return planeInfo;
	}

	private TransitEntity paraseTraintByElement(Element traint_st) throws Exception {
		String[] a_name=traint_st.getElementsByClass("a_name").get(0).text().split(" ");
		String carrierName=a_name[0];
		String flightNo=a_name[1];
		String actuallyFlightNo=null;
		String carrierKey=flightNo.substring(0, 2);
		String flightType=traint_st.getElementsByClass("a_model").get(0).text();
		if(flightType.indexOf("共享")>1){
			flightType=flightType.replace(" ", "").replace("共享", "");
			String title=traint_st.getElementsByClass("lnk_a").get(0).attr("title");
			actuallyFlightNo=title.replaceAll("[\u4e00-\u9fa5]", "").replace("：", "");
		}
		String startTime=traint_st.getElementsByClass("a_tm_dep").get(0).text();
		String endTime=traint_st.getElementsByClass("a_tm_arv").get(0).text();
		String fromAirPortName=traint_st.getElementsByClass("a_lacal_dep").get(0).text();
		String toAirPortName=traint_st.getElementsByClass("a_local_arv").get(0).text();
		TransitEntity traint= PlaneInfoEntityBuilder.buildTransitEntity(flightNo, actuallyFlightNo, carrierKey, carrierName, 
				carrierName, null, fromAirPortName, null, toAirPortName, flightType);
		traint.setStartTime(PlaneInfoEntityBuilder.getFlightTime(taskQueue.getFlightDate(), startTime));
		traint.setEndTime(PlaneInfoEntityBuilder.getFlightTime(taskQueue.getFlightDate(), endTime));
		//开始时间大于结束时间 就+1
		if(traint.getStartTime().compareTo(traint.getEndTime())>0){
			Calendar c=Calendar.getInstance();
			c.setTime(traint.getEndTime());
			c.add(Calendar.DAY_OF_MONTH, 1);
			traint.setEndTime(c.getTime());
		}
		return traint;
	}

	/**
	 * 解析价格
	 * @param prc
	 * @return
	 */
	public String changToPrice(Element prc) {
		String[] numbers=prc.text().split(" ");
		String width=RegHtmlUtil.retrieveLinks(prc.html(), getRegex1(), 1).get(0);
		int leng=Integer.parseInt(width)/11;
		List<String> listSize=RegHtmlUtil.retrieveLinks(prc.html(), getRegex(), 1);
		StringBuilder price=new StringBuilder(numbers[0]);
		int i=1;
		for(String size:listSize){
			int t =Integer.parseInt(size);
			if(t>0)
				continue;
			t=-t/11;
			price.setCharAt(leng-t, numbers[i].charAt(0));
			i++;
		}
		return price.toString();
	}
	
	private String getRegex(){
		String regex = "<b style=\"left:(.+?)px\">";
		return regex;	
	}
	
	private String getRegex1(){
		String regex = "<b style=\"width:(.+?)px;left:";
		return regex;	
	}

	/**
	 * 解析国内单程
	 * 
	 * @param obj
	 * @return
	 * @throws Exception
	 */
	@SuppressWarnings("unchecked")
	public List<Object> paraseDomeOneWay(Object obj) throws Exception {
		List<AbstractPlaneInfoEntity> result = new ArrayList<AbstractPlaneInfoEntity>();
		
		
		JSONObject j;
		JSONObject onewayData;
		JSONObject flightInfo;
		JSONObject priceInfo;// 最低票价info
		JSONObject compInfo;// 公司对应关系json
		JSONObject tuijianPriceInfo;// 推荐票价
		String serverIP;
		String queryID;
		JSONObject agentInfo;// 代理
		try {
			j = (JSONObject) obj;
			
			
			
			if ( j.getJSONObject("oneway_data").getJSONObject("flightInfo").isEmpty()) {
				int size=crawlMoreTry;
				return fetchMoreDomeOneWay(j,size);
			}
			
			serverIP = j.getString("serverIP");
			queryID = j.getString("queryID");
			JSONObject realData= this.getRealData(serverIP,queryID);
			
			if(null!=realData && !realData.getJSONObject("flightInfo").isEmpty()){
				compInfo = realData.getJSONObject("carrierInfo");
				flightInfo = realData.getJSONObject("flightInfo");
				priceInfo = realData.getJSONObject("priceInfo");
				tuijianPriceInfo = realData.getJSONObject("recommendInfo");
			}else{
				onewayData = j.getJSONObject("oneway_data");
				compInfo = onewayData.getJSONObject("carrierInfo");
				flightInfo = onewayData.getJSONObject("flightInfo");
				priceInfo = onewayData.getJSONObject("priceInfo");
				tuijianPriceInfo = onewayData.getJSONObject("recommendInfo");
			}
			agentInfo = j.getJSONObject("vendors");
			
			//求最低价航班
			Double lowerPrice= 0d;
			String lowerFlightNo=null;
			for(String k:(Set<String>) priceInfo.keySet()){
				JSONObject price=priceInfo.getJSONObject(k);
				Double lowpr=price.getDouble("lowpr");
				if(lowerPrice==0 || lowerPrice>lowpr){
					lowerPrice=lowpr;
					lowerFlightNo=k;
				}
					
			}
			
			for (String k : (Set<String>) flightInfo.keySet()) {
				JSONObject fInfo;
				JSONObject pInfo;
				JSONObject tInfo;
				JSONObject lastFinfo = null;

				SinglePlaneInfoEntity singlePlaneInfoEntity;
				CabinEntity c;
				TransitEntity t;
				List<PriceCollect> prices = new ArrayList<PriceCollect>();
				try {
					fInfo = flightInfo.getJSONObject(k);
					if (fInfo.get("flights") != null) {
						lastFinfo = fInfo.getJSONObject("flights").getJSONObject(k.replaceAll(".*/", "").replaceAll("\\|.*", ""));
						fInfo = fInfo.getJSONObject("flights").getJSONObject(k.replaceAll("/.*", ""));
					}
					if (fInfo.isNullObject()) {
						continue;
					}
					if (lastFinfo == null) {
						lastFinfo = fInfo;
					}
					singlePlaneInfoEntity = (SinglePlaneInfoEntity) PlaneInfoEntityBuilder.buildPlaneInfo(taskQueue, fInfo.getString("ca"), compInfo.getJSONObject(fInfo.getString("ca")).getString("zh"), compInfo.getJSONObject(fInfo.getString("ca"))
							.getString("full"), fInfo.getString("dt"), lastFinfo.getString("at"), k.replaceAll("\\|.*", "").replaceAll("/.*", ""), null, null, null, fInfo.getString("pt"));
					// singlePlaneInfoEntity.setFlightDuration();
					pInfo = priceInfo.getJSONObject(k);
					if (pInfo != null && !pInfo.isNullObject() && !pInfo.isEmpty()) {// 作为国内单程，这个地方是一个比较完整的仓位信息
						c = new CabinEntity();
						c.setPrice(pInfo.getDouble("lowpr"));
						if(pInfo.containsKey("cabin"))
							c.setSubCabinName(pInfo.getString("cabin"));
						if(pInfo.containsKey("tc"))
							c.setCabinType(pInfo.getString("tc"));
						//c.setTaxesPrice(170d);
						//c.setOriginalPrice(pInfo.getDouble("lowpr") + 170d);
						singlePlaneInfoEntity.getCabins().add(c);
						//prices.add(new PriceCollect(pInfo.getDouble("lowpr"), 170d, pInfo.getDouble("lowpr") + 170d));
						prices.add(new PriceCollect(null, pInfo.getDouble("lowpr"), null));
					}
					tInfo = tuijianPriceInfo.getJSONObject(k);
					if (tInfo != null && !tInfo.isNullObject() && !tInfo.isEmpty()) {
						tInfo = (JSONObject) tInfo.values().iterator().next();
						c = new CabinEntity();
						if (tInfo.get("cabin") != null) {
							c.setSubCabinName(tInfo.getString("cabin"));
						}
						c.setTaxesPrice(tInfo.getDouble("tax"));
						c.setPrice(tInfo.getDouble("pr"));
						Double sum=null;
						if(tInfo.getDouble("tax")>0 && tInfo.getDouble("pr")>0)
							sum=tInfo.getDouble("pr") + tInfo.getDouble("tax");
						c.setOriginalPrice(sum);
						if(tInfo.getDouble("pr")>0){
							singlePlaneInfoEntity.getCabins().add(c);
							prices.add(new PriceCollect(tInfo.getDouble("tax"), tInfo.getDouble("pr"), sum));
						}
						
					}

					// 经停
					addStopover(singlePlaneInfoEntity, flightInfo.getJSONObject(k), k);

					// 中转
					if (k.indexOf("/") != -1) {
						JSONObject flights = flightInfo.getJSONObject(k).getJSONObject("flights");
						for (String no : k.replaceAll("\\|.*", "").split("/")) {
							try {
								JSONObject flight = flights.getJSONObject(no);
								t = PlaneInfoEntityBuilder.buildTransitEntity(no, no, flight.getString("ca"), null, null, flight.getString("da"), flight.getString("dc"), flight.getString("aa"), flight.getString("ac"), flight.getString("pt"));
								t.setStartTime(PlaneInfoEntityBuilder.getFlightTime(taskQueue.getFlightDate(), flight.getString("dt")));
								t.setEndTime(PlaneInfoEntityBuilder.getFlightTime(taskQueue.getFlightDate(), flight.getString("at")));
							} catch (Exception e) {
								//logger.info("添加国内单程[" + no + "]中转额外信息失败");
								//logger.info(e);
								t = new TransitEntity();
								t.setFlightNo(no);
							}
							singlePlaneInfoEntity.getTransits().add(t);
						}
					}
					//只有航线的最低价(第一个价格)，才请求更新代理人价格
					if(null!=lowerFlightNo && k.equals(lowerFlightNo))
						try {
							setDomesticPlaneEntityAgent(singlePlaneInfoEntity, prices, k, serverIP, queryID, agentInfo);
						} catch (Exception e) {
							logger.error(e);
						}
					// singlePlaneInfoEntity.setTotalLowestPrice(super.getPriceByType(prices, "lower"));
					// singlePlaneInfoEntity.setTotalHighestPrice(super.getPriceByType(prices, "hight"));
					// 排序
					PriceCollect.buildPrice(singlePlaneInfoEntity, prices);

					result.add(singlePlaneInfoEntity);
					/*this.showDirect(singlePlaneInfoEntity);*/
				} catch (Exception e) {
					e.printStackTrace();
					logger.error(e);
				} finally {
					fInfo = null;
					pInfo = null;
					tInfo = null;
					singlePlaneInfoEntity = null;
					c = null;
					t = null;
				}
			}
		} finally {
			j = null;
			onewayData = null;
			flightInfo = null;
			priceInfo = null;// 最低票价info
			compInfo = null;// 公司对应关系json
			tuijianPriceInfo = null;// 推荐票价
		}
		return Arrays.asList(result.toArray());
	}
	
	/**
	 * 获得国内真实的价格
	 * @param serverIP
	 * @param queryID
	 * @return
	 */
	private JSONObject getRealData(String serverIP, String queryID) {
		  HttpClient h;
		  HttpGet g = null;
		  String page = null;
		  JSONObject json;
		  Map<String, String> p = new HashMap<String, String>();
		 int token=(int) (Math.random()*100000);
		  p.put("token", token+"");
	      p.put("arrivalCity", getCity(this.taskQueue.getToCityName()));
	      p.put("deduce", "true");
	      p.put("departureCity", getCity(this.taskQueue.getFromCityName()));
	      p.put("departureDate", taskQueue.getFlightDate());
	      p.put("returnDate", taskQueue.getFlightDate());
	      p.put("from", "fi_dom_search");
	      p.put("locale", "zh");
	      p.put("nextNDays", "0");
	      p.put("searchLangs", "zh");
	      p.put("searchType", "OneWayFlight");
	      p.put("status", System.currentTimeMillis()+"");
	      p.put("serverIP", serverIP);
	      String queryId=unQueryID(queryID);
	      p.put("queryID", queryId);
	      try{
	    	    h = getHttpClient();
				g = super.getBaseGet("http://flight.qunar.com/twell/flight/tags/deduceonewayflight_groupdata.jsp", p);
				page = super.excuteRequest(h, g, true);
				super.appendPageContents(page);//设置源网页数据
				json = JSONObject.fromObject(page.trim().replaceAll("^\\(|\\)$", ""));
				return json;
	      }catch (Exception e) {
				e.printStackTrace();
				logger.error(e);
		  } finally {
			g=null;
			p=null;
			page=null;
		}
		return null;
	}

	/**
	 * 获得更多的国内单程航班
	 * @param j 
	 * @return
	 * @throws Exception 
	 */
	  private List<Object> fetchMoreDomeOneWay(JSONObject j,int size) throws Exception {
		  HttpClient h;
		  HttpGet g = null;
		  Map<String, String> p = new HashMap<String, String>();
		  String page = null;
		  JSONObject json;
		  int token=(int) (Math.random()*100000);
		  String serverIP = j.getString("serverIP");
	      String queryID = j.getString("queryID");
		  p.put("token", token+"");
	      p.put("arrivalCity", getCity(this.taskQueue.getToCityName()));
	      p.put("deduce", "true");
	      p.put("departureCity", getCity(this.taskQueue.getFromCityName()));
	      p.put("departureDate", taskQueue.getFlightDate());
	      p.put("returnDate", taskQueue.getFlightDate());
	      p.put("from", "fi_dom_search");
	      p.put("locale", "zh");
	      p.put("nextNDays", "0");
	      p.put("searchLangs", "zh");
	      p.put("searchType", "OneWayFlight");
	      p.put("status", System.currentTimeMillis()+"");
	      p.put("serverIP", serverIP);
	      
	      String queryId=unQueryID(queryID);
	      p.put("queryID", queryId);
	      try {
	    	h = getHttpClient();
			g = super.getBaseGet("http://flight.qunar.com/twell/flight/tags/OneWayFlight_data_more.jsp", p);
			page = super.excuteRequest(h, g, true);
			super.appendPageContents(page);//设置源网页数据
			json = JSONObject.fromObject(page.trim().replaceAll("^\\(|\\)$", ""));
			List<Object> list=this.paraseMoreDomeOneWay(json);
			if(null==list && size>0){
				size--;
				return fetchMoreDomeOneWay(j,size);
			}else{
				return list;
			}
		} finally {
			page = null;
			if (g != null) {
				g.releaseConnection();
				g = null;
			}
			h = null;
			json=null;
		}
	}

	private List<Object> paraseMoreDomeOneWay(JSONObject json) throws Exception {
		List<AbstractPlaneInfoEntity> result = new ArrayList<AbstractPlaneInfoEntity>();
		if(null==json || json.getJSONObject("data")==null )
			return null;
		JSONObject data;
		JSONObject carrierInfo;
		JSONObject priceInfo;
		JSONObject flight;
		JSONObject airportInfo;
		try {
			data=json.getJSONObject("data");
			if(data.isEmpty())
				return null;
			carrierInfo=json.getJSONObject("carrierInfo");
			priceInfo=json.getJSONObject("priceInfo");
			airportInfo=json.getJSONObject("airportInfo");
			
			for (String k : (Set<String>) data.keySet()) {
				try {
					SinglePlaneInfoEntity singlePlaneInfoEntity;
					CabinEntity c;
					ArrayList<TransitEntity> transits = new ArrayList<TransitEntity>();
					flight=data.getJSONObject(k);
					String[] keys=k.split("\\|");
					for (String key : keys) {
						if(key.indexOf("-")>=0)
							continue;
						JSONObject transit=flight.getJSONObject(key);
						TransitEntity t=PlaneInfoEntityBuilder.buildTransitEntity(key, null, transit.getString("ca"), carrierInfo.getJSONObject(transit.getString("ca")).getString("zh"),
								carrierInfo.getJSONObject(transit.getString("ca")).getString("full"), transit.getString("da"),airportInfo.getJSONObject(transit.getString("da")).getString("full") ,
								transit.getString("aa"),airportInfo.getJSONObject(transit.getString("aa")).getString("full"), transit.getString("pt"), TransitEntity.class);
						t.setStartTime(PlaneInfoEntityBuilder.getFlightTime(transit.getString("dd"), transit.getString("dt")));
						t.setEndTime(PlaneInfoEntityBuilder.getFlightTime(transit.getString("dd"), transit.getString("at")));
						transits.add(t);
					}
					if(transits.size()>0){
						TransitEntity t =transits.get(0);
						singlePlaneInfoEntity=PlaneInfoEntityBuilder.buildPlaneInfo(taskQueue, t.getCarrierKey(), t.getCarrierName(), t.getCarrierFullName(),
								null, null, t.getFlightNo(), priceInfo.getJSONObject(k).getString("lowpr"), null, null,
								t.getFlightType(), null, null, null, null, SinglePlaneInfoEntity.class);
						singlePlaneInfoEntity.setStartTime(t.getStartTime());
						singlePlaneInfoEntity.setEndTime(transits.get(transits.size()-1).getEndTime());
						if(transits.size()>1)
							singlePlaneInfoEntity.setTransits(transits);
						result.add(singlePlaneInfoEntity);
					}
				} catch (Exception e) {
					logger.error(e);
				}

			}
			
		}finally {
			data=null;
			carrierInfo=null;
			priceInfo=null;
			flight=null;
			airportInfo=null;
		}
		
		return Arrays.asList(result.toArray());
	}

		
	/**
	 * 获得国内单程代理 和最低价子舱
	 * @param entity
	 * @param prices
	 * @param key
	 * @param serverIP
	 * @param queryID
	 * @param agentInfos
	 * @return
	 */
	private boolean setDomesticPlaneEntityAgent(SinglePlaneInfoEntity entity, List<PriceCollect> prices, String key, String serverIP, String queryID, JSONObject agentInfos){
		boolean flag = false;
		HttpClient h;
		HttpGet g;
		Map<String, String> p = new HashMap<String, String>();
		String jsonStr;
		JSONObject json;
		JSONObject agents;
		
		AgentEntity agentEntity;
		String page = null;
		try {
			if (isConformFlightNo(entity) && this.isGoOrReturnDirect(entity)) {
				Thread.sleep(1000);
				h = getHttpClient();
				
				int token=(int) (Math.random()*100000);
				p.put("_token", token+"");
				
				p.put("departureCity", getCity(this.taskQueue.getFromCityName()));
				p.put("arrivalCity", getCity(this.taskQueue.getToCityName()));
				p.put("deduce", "true");
				p.put("departureDate", taskQueue.getFlightDate());
				p.put("returnDate", taskQueue.getFlightDate());
				p.put("flightCode", key);
				p.put("from", "fi_dom_search");
				p.put("locale", "zh");
				p.put("label", "all");
				p.put("lowflight", "true");
				p.put("mergeFlag", "0");
				p.put("nextNDays", "0");
				String queryId=unQueryID(queryID);
				p.put("queryID", queryId);
				p.put("searchLangs", "zh");
				p.put("searchType", "OneWayFlight");
				p.put("serverIP", serverIP);
				p.put("status", System.currentTimeMillis() + "");
				p.put("tabKey", "ap");
				p.put("ex_track", "bd_zhixin_flight_fgn_title");
				
				g = super.getBaseGet("http://flight.qunar.com/twell/flight/tags/onewayflight_groupinfo.jsp", p);
				g.addHeader("Referer", "http://flight.qunar.com/");
				page = super.excuteRequest(h, g, true);
				
				super.appendPageContents(page);//设置源网页数据
				jsonStr = RegHtmlUtil.regStr(page, ".*?\\((.*)\\)", 1);
				json = JSONObject.fromObject(jsonStr);
				
				Double lowerPrice=0d;
				
				String subCabinName=null;
				
				// 解析
				if (json.get("priceData") != null && json.getJSONObject("priceData").get(key) != null ) {
					agents=json.getJSONObject("priceData").getJSONObject(key);
					Iterator it = agents.keys(); 
					 while (it.hasNext()) {  
						 String agentId = (String) it.next();
						 String[] strs=agentId.split("_");
						 JSONObject agentInfo=agentInfos.getJSONObject(strs[0]);//代理商信息
						 JSONObject agent=agents.getJSONObject(agentId);//代理价格信息
						 Double agentPrice=agent.getDouble("npr");
						 if(agentPrice<0)
							 continue;
						 String cname = agentInfo.getJSONObject("info").get("cname") == null ? agentInfo.getString("name") : agentInfo.getJSONObject("info").getString("cname");
						 String addr = agentInfo.getJSONObject("info").get("addr") == null ? null : agentInfo.getJSONObject("info").getString("addr");
						 agentEntity = PlaneInfoEntityBuilder.buildAgent(agentInfo.getString("name"), agent.getString("npr"), null, getAgentTypeByCompanyName(cname), cname, addr, AgentEntity.class);
						
						 if(lowerPrice==0 || lowerPrice>=agentPrice){
							 lowerPrice=agentPrice;
							 subCabinName=agent.getString("cabin");
						 }
							 
							// 14年7月增加税费和合计价
							try {
								agentEntity.setTaxesPrice(agent.getDouble("ntax"));
								agentEntity.setOriginalPrice(agent.getDouble("ntax") + agent.getDouble("npr"));
							} catch (Exception e) {
							}
							prices.add(new PriceCollect(agent.getDouble("npr"), agent.getDouble("ntax"), agent.getDouble("ntax") + agent.getDouble("npr")));
							entity.getAgents().add(agentEntity);
							logger.info(String.format("[获取更多单程代理][%s][%s]成功构建代理实体[%s][%s][%s]", entity.getFlightNo(), entity.getFlightDate(), agentEntity.getName(), agentEntity.getPrice(), agentEntity.getTaxesPrice()));
					 }
					 if(null!=subCabinName && !"".equals(subCabinName)){
						    boolean  islower=true;
							for(CabinEntity cabin:entity.getCabins()){
								if(lowerPrice==cabin.getPrice()){
									cabin.setSubCabinName(subCabinName);
									islower=false;
									break;
								}
								if(lowerPrice>cabin.getPrice())
									islower=false;
							}
							if(islower){
								CabinEntity c=new CabinEntity();
								c.setPrice(lowerPrice);
								c.setSubCabinName(subCabinName);
								entity.getCabins().add(c);
							}
					 }
					flag = true;
				}

			}
		} catch (Exception e) {
			flag = false;
			logger.error(e);
		} finally {
			page = null;
		}
		return flag;
	}

	/**
	 * 解析国际单程
	 * 
	 * @param obj
	 * @return
	 * @throws Exception
	 */
	@SuppressWarnings("unchecked")
	private List<Object> paraseInterOneWay(Object obj) throws Exception {
		List<AbstractPlaneInfoEntity> result = new ArrayList<AbstractPlaneInfoEntity>();
		JSONObject j;
		JSONObject onewayData;
		JSONObject compInfo;// 公司对应关系json
		JSONObject flightInfo;
		JSONObject priceInfo;// 最低票价info
		JSONObject tuijianPriceInfo;// 推荐票价
		JSONObject liuxuePriceInfo;// 留学生票价
		JSONObject agentInfo;// 代理
		SinglePlaneInfoEntity singlePlaneInfoEntity;
		String serverIP;
		String queryID;
		JSONObject lastFinfo;
		try {
			j = (JSONObject) obj;
			onewayData = j.getJSONObject("oneway_data");
			compInfo = onewayData.getJSONObject("carrierInfo");
			flightInfo = onewayData.getJSONObject("flightInfo");
			priceInfo = onewayData.getJSONObject("priceInfo");
			tuijianPriceInfo = onewayData.getJSONObject("priceData");
			liuxuePriceInfo = onewayData.getJSONObject("tagPriceData");
			agentInfo = j.getJSONObject("vendors");
			serverIP = j.getString("serverIP");
			queryID = j.getString("queryID");
			// key形式如下
			// AC32/AC876/AC9443|2013-11-29
			for (String k : (Set<String>) flightInfo.keySet()) {
				JSONObject fInfo;
				JSONObject flights_1;
				JSONObject pInfo;
				JSONObject lInfo;
				JSONObject tInfo;
				TransitEntity t;
				List<PriceCollect> prices = new ArrayList<PriceCollect>();
				try {
					fInfo = flightInfo.getJSONObject(k);
					if (fInfo.get("flights") == null) {
						flights_1 = fInfo;
						lastFinfo = fInfo;
					} else {
						lastFinfo = fInfo.getJSONObject("flights").getJSONObject(k.replaceAll(".*/", "").replaceAll("\\|.*", ""));
						flights_1 = fInfo.getJSONObject("flights").getJSONObject(k.replaceAll("/.*", ""));
					}
					if (flights_1.isNullObject()) {
						continue;
					}
					singlePlaneInfoEntity = (SinglePlaneInfoEntity) PlaneInfoEntityBuilder.buildPlaneInfo(taskQueue, flights_1.getString("ca"), compInfo.getJSONObject(flights_1.getString("ca")).getString("zh"),
							compInfo.getJSONObject(flights_1.getString("ca")).getString("full"), flights_1.getString("dt"), lastFinfo.getString("at"), k.replaceAll("\\|.*", "").replaceAll("/.*", ""), null, null, null, flights_1.getString("pt"));
					// 增加飞行总时间
					try {
						singlePlaneInfoEntity.setFlightDuration(getLong(flightInfo.getJSONObject(k).getLong("dur")));
					} catch (Exception e) {
						//logger.info("增加国际单程总时间失败");
						//logger.info(flightInfo.getJSONObject(k));
						//logger.info(e);
					}

					// 经停
					addStopover(singlePlaneInfoEntity, flightInfo.getJSONObject(k), k);
					// 中转
					if (k.indexOf("/") != -1) {
						JSONObject flights = flightInfo.getJSONObject(k).getJSONObject("flights");
						for (String no : k.replaceAll("\\|.*", "").split("/")) {
							try {
								JSONObject flight = flights.getJSONObject(no);
								t = PlaneInfoEntityBuilder.buildTransitEntity(no, no, flight.getString("ca"), null, null, flight.getString("da"), flight.getString("dc"), flight.getString("aa"), flight.getString("ac"), flight.getString("pt"));
								t.setStartTime(PlaneInfoEntityBuilder.getFlightTime(taskQueue.getFlightDate(), flight.getString("dt")));
								t.setEndTime(PlaneInfoEntityBuilder.getFlightTime(taskQueue.getFlightDate(), flight.getString("at")));
							} catch (Exception e) {
								//logger.info("添加国际单程[" + no + "]中转额外信息失败");
								//logger.info(e);
								t = new TransitEntity();
								t.setFlightNo(no);
							}
							singlePlaneInfoEntity.getTransits().add(t);
						}
					}
					boolean b = setSinglePlaneInfoEntityMoreAgent(singlePlaneInfoEntity, prices, k, serverIP, queryID, agentInfo);
					if (!b) {// 如果获取更多代理失败只能对现有信息进行归纳
						pInfo = priceInfo.getJSONObject(k);
						if (pInfo != null && !pInfo.isNullObject() && !pInfo.isEmpty()) {
							singlePlaneInfoEntity.setTotalLowestPrice(pInfo.getDouble("lownpr"));
							prices.add(new PriceCollect(pInfo.getDouble("lownpr"), pInfo.getDouble("tax"), pInfo.getDouble("lownpr") + pInfo.getDouble("tax")));
						}
						// 推荐票价
						tInfo = tuijianPriceInfo.getJSONObject(k);
						setSingleCabinAndAgentInfo(singlePlaneInfoEntity, tInfo, "推荐票价", agentInfo, prices);
					}
					lInfo = liuxuePriceInfo.getJSONObject(k);
					// 看下有没有留学生票价
					setSingleCabinAndAgentInfo(singlePlaneInfoEntity, lInfo, "留学生票", agentInfo, prices);
					// singlePlaneInfoEntity.setTotalLowestPrice(super.getPriceByType(prices, "lower"));
					// singlePlaneInfoEntity.setTotalHighestPrice(super.getPriceByType(prices, "hight"));
					// 设置价格
					PriceCollect.buildPrice(singlePlaneInfoEntity, prices);

					setPagePriceCabin(singlePlaneInfoEntity);
					result.add(singlePlaneInfoEntity);
					this.showDirect(singlePlaneInfoEntity);
				} catch (Exception e) {
					logger.error(String.format("[%s]解析[%s] [%s]-[%s] [%s]-[%s] 详情[%s] 错误[%s]", super.taskQueue.getGrabChannel(), super.getRouteType().getName(), taskQueue.getFromCity(), taskQueue.getToCity(), taskQueue.getFlightDate(),
							taskQueue.getReturnGrabDate(), k.toString(), e));
				} finally {
					fInfo = null;
					pInfo = null;
					lInfo = null;
					tInfo = null;
					t = null;
				}
			}
		} finally {
			j = null;
			onewayData = null;
			compInfo = null;// 公司对应关系json
			flightInfo = null;
			priceInfo = null;// 最低票价info
			tuijianPriceInfo = null;// 推荐票价
			liuxuePriceInfo = null;// 留学生票价
			singlePlaneInfoEntity = null;
		}

		return Arrays.asList(result.toArray());
	}
	
	

	/**
	 * 设置获取更多国际单程代理
	 * 
	 * @param entity
	 * @param prices
	 * @param key
	 * @param serverIP
	 * @param queryID
	 * @param agentInfos
	 * @return
	 */
	private boolean setSinglePlaneInfoEntityMoreAgent(SinglePlaneInfoEntity entity, List<PriceCollect> prices, String key, String serverIP, String queryID, JSONObject agentInfos) {
		boolean flag = false;
		HttpClient h;
		HttpGet g;
		Map<String, String> p = new HashMap<String, String>();
		String jsonStr;
		JSONObject json;
		JSONObject info;
		AgentEntity agentEntity;
		String page = null;
		try {
			if (isConformFlightNo(entity) && this.isGoOrReturnDirect(entity)) {
				Thread.sleep(1000);
				h = getHttpClient();
				p.put("_token", "");
				p.put("departureCity", taskQueue.getFromCity());
				p.put("arrivalCity", taskQueue.getToCity());
				p.put("deduce", "true");
				p.put("departureDate", taskQueue.getFlightDate());
				p.put("returnDate", taskQueue.getFlightDate());
				p.put("flightCode", key);
				p.put("from", "fi_ont_search");
				p.put("locale", "zh");
				p.put("mergeFlag", "0");
				p.put("nextNDays", "0");
				p.put("queryID", queryID);
				p.put("searchLangs", "zh");
				p.put("searchType", "OneWayFlight");
				p.put("serverIP", serverIP);
				p.put("status", System.currentTimeMillis() + "");
				p.put("tabKey", "ap");
				
//				g = super.getBaseGet("http://flight.qunar.com/twelli/flight/tags/onewayflight_groupinfo_inter.jsp", p);
				g = super.getBaseGet("http://flight.qunar.com/twell/flight/tags/onewayflight_groupinfo.jsp", p);
				g.addHeader("Referer", "http://flight.qunar.com/");
				page = super.excuteRequest(h, g, true);
				super.appendPageContents(page);//设置源网页数据
				jsonStr = RegHtmlUtil.regStr(page, ".*?\\((.*)\\)", 1);
				json = JSONObject.fromObject(jsonStr);
				if (json.get("tabLowpr") != null && json.getJSONObject("tabLowpr").get("ap") != null) {
					entity.setTotalLowestPrice(json.getJSONObject("tabLowpr").getDouble("ap"));
				}

				// 解析
				if (json.get("priceData") != null && json.getJSONObject("priceData").get(key) != null && json.getJSONObject("priceData").getJSONObject(key).get("A") != null) {
					for (Object o : json.getJSONObject("priceData").getJSONObject(key).getJSONObject("A").values()) {
						info = JSONObject.fromObject(o);
						JSONObject agentInfo = agentInfos.getJSONObject(info.getString("wrid"));
						/*
						 * if(agentInfo.getString("name").matches("^\\w*$")){ logger.info(String.format("代理商名称[%s]全英文,过滤", agentInfo.getString("name"))); continue; }
						 */
						String cname = agentInfo.getJSONObject("info").get("cname") == null ? agentInfo.getString("name") : agentInfo.getJSONObject("info").getString("cname");
						String addr = agentInfo.getJSONObject("info").get("addr") == null ? null : agentInfo.getJSONObject("info").getString("addr");
						agentEntity = PlaneInfoEntityBuilder.buildAgent(agentInfo.getString("name"), info.getString("npr"), null, getAgentTypeByCompanyName(cname), cname, addr, AgentEntity.class);

						// 14年7月增加税费和合计价
						try {
							agentEntity.setTaxesPrice(info.getDouble("ntax"));
							agentEntity.setOriginalPrice(info.getDouble("ntax") + info.getDouble("npr"));
						} catch (Exception e) {
							//logger.info("国际单程设置代理税费，合计价失败");
							//logger.info(info);
						}

						prices.add(new PriceCollect(info.getDouble("npr"), info.getDouble("ntax"), info.getDouble("ntax") + info.getDouble("npr")));
						entity.getAgents().add(agentEntity);
						logger.info(String.format("[获取更多单程代理][%s][%s]成功构建代理实体[%s][%s][%s]", entity.getFlightNo(), entity.getFlightDate(), agentEntity.getName(), agentEntity.getPrice(), agentEntity.getTaxesPrice()));
					}
					flag = true;
				}

			}
		} catch (Exception e) {
			flag = false;
			logger.error(e);
		} finally {
			page = null;
		}
		return flag;
	}

	private int getAgentTypeByCompanyName(String name) {
		if (name == null) {
			return 2;
		}
		if (name.matches(".*中国南方航空.*") || name.matches(".*中国国际航空.*") || name.matches(".*中国厦门航空.*") || name.matches(".*中国东方航空.*") || name.matches(".*中国深圳航空.*")) {
			return 0;
		} else {
			return 2;
		}
	}

	public boolean setDoublePlaneInfoEntityMoreAgent(DoublePlaneInfoEntity entity, List<PriceCollect> prices, String serverIP, String queryID) {
		boolean flag = false;
		HttpClient h;
		HttpGet g;
		Map<String, String> p = new HashMap<String, String>();
		String jsonStr;
		JSONObject json;
		JSONObject info;
		ReturnAgentEntity returnAgentEntity;
		List<PriceCollect> rePrices;
		String page = null;
		try {
			if (isConformFlightNo(entity) && this.isGoOrReturnDirect(entity) && entity.getReturnPlaneInfos() != null) {
				for (ReturnDoublePlaneInfoEntity reEntity : entity.getReturnPlaneInfos()) {
					String key;
					try {
						if (!isConformFlightNo(reEntity) || !isGoOrReturnDirect(reEntity)) {
							continue;
						}
						Thread.sleep(2000);
						rePrices = new ArrayList<PriceCollect>();
						key = entity.getFlightNo() + "_" + reEntity.getFlightNo();
						h = getHttpClient();
						p.put("_token", "53392");
						p.put("departureCity", taskQueue.getFromCity());
						p.put("arrivalCity", taskQueue.getToCity());
						p.put("deduce", "true");
						p.put("departureDate", taskQueue.getFlightDate());
						p.put("returnDate", taskQueue.getReturnGrabDate());
						p.put("flightCodePair", key);
						p.put("fcarrier", "");
						p.put("locale", "zh");
						p.put("mergeFlag", "0");
						p.put("nextNDays", "0");
						p.put("queryID", queryID);
						p.put("reset", "false");
						p.put("searchLangs", "zh");
						p.put("searchType", "RoundTripFlight");
						p.put("serverIP", serverIP);
						p.put("status", System.currentTimeMillis() + "");
						p.put("tabKey", "ap");
						g = super.getBaseGet("http://flight.qunar.com/twelli/flight/tags/thunder_interroundtrip_flight_info.jsp?", p);
						g.addHeader("Referer", "http://flight.qunar.com/");
						page = super.excuteRequest(h, g, true);
						super.appendPageContents(page);
						jsonStr = RegHtmlUtil.regStr(page, ".*?\\((.*)\\)", 1);
						json = JSONObject.fromObject(jsonStr);
						/*
						 * //解析 if(json.get("outPriceData")!=null && json.get("retPriceData")!=null && json.getJSONObject("outPriceData").get("0"+entity.getFlightNo())!=null &&
						 * json.getJSONObject("outPriceData").getJSONObject("0"+entity.getFlightNo()).get("A")!=null && json.getJSONObject("retPriceData").get("0"+reEntity.getFlightNo())!=null &&
						 * json.getJSONObject("retPriceData").getJSONObject("0"+reEntity.getFlightNo()).get("A")!=null ){
						 * 
						 * }
						 */

						String k = "0" + entity.getFlightNo() + "|" + "1" + reEntity.getFlightNo();
						if (json.get("vendors") != null && !json.getJSONObject("vendors").isEmpty()) {

							for (Object obj : json.getJSONObject("vendors").keySet()) {
								String agentId = (String) obj;
								if (!agentInfos.containsKey(agentId)) {
									agentInfos.put(agentId, json.getJSONObject("vendors").get(agentId));
								}
							}
						}
						// 解析
						if (json.get("packagePriceData") != null && json.getJSONObject("packagePriceData").get(k) != null && json.getJSONObject("packagePriceData").getJSONObject(k).get("A") != null) {
							for (Object o : json.getJSONObject("packagePriceData").getJSONObject(k).getJSONObject("A").values()) {
								info = JSONObject.fromObject(o);
								if (agentInfos.get(info.getString("wrid")) == null) {
									logger.info(String.format("找不到代理商[%s]", info.getString("wrid")));
									continue;
								}
								JSONObject agentInfo = agentInfos.getJSONObject(info.getString("wrid"));
								if (agentInfo.getString("name").matches("^\\w*$")) {
									logger.info(String.format("代理商名称[%s]全英文,过滤", agentInfo.getString("name")));
									continue;
								}
								String cname = agentInfo.getJSONObject("info").get("cname") == null ? agentInfo.getString("name") : agentInfo.getJSONObject("info").getString("cname");
								String addr = agentInfo.getJSONObject("info").get("addr") == null ? null : agentInfo.getJSONObject("info").getString("addr");
								returnAgentEntity = PlaneInfoEntityBuilder.buildAgent(agentInfo.getString("name"), info.getString("npr"), null, getAgentTypeByCompanyName(cname), cname, addr, ReturnAgentEntity.class);
								prices.add(new PriceCollect(info.getDouble("npr"), info.getDouble("ntax"), info.getDouble("npr") + info.getDouble("ntax")));

								rePrices.add(new PriceCollect(info.getDouble("npr"), info.getDouble("ntax"), info.getDouble("npr") + info.getDouble("ntax")));
								reEntity.getReturnAgents().add(returnAgentEntity);
								logger.info(String.format("[获取更多往返代理][%s][%s][%s][%s]成功构建代理实体[%s][%s]", entity.getFlightNo(), reEntity.getFlightNo(), taskQueue.getFlightDate(), taskQueue.getReturnGrabDate(), returnAgentEntity.getAgentName(),
										returnAgentEntity.getPrice()));
							}
							// reEntity.setTotalLowestPrice(super.getPriceByType(rePrices, "lower"));
							// reEntity.setTotalHighestPrice(super.getPriceByType(rePrices, "hight"));
							PriceCollect.buildPrice(reEntity, rePrices);
							flag = true;
						}
					} catch (Exception e) {
						logger.error(e);
					} finally {
						page = null;
						key = null;
					}
				}
			}
		} catch (Exception e) {
			logger.error(e);
		} finally {

		}
		return flag;
	}

	@SuppressWarnings("unchecked")
	private void setSingleCabinAndAgentInfo(SinglePlaneInfoEntity entity, JSONObject priceInfo, String productName, JSONObject agentInfo, List<PriceCollect> prices) {
		if (priceInfo == null || priceInfo.isNullObject() || priceInfo.isEmpty()) {
			return;
		}
		CabinEntity c;
		double price;
		double tax;
		String key;
		AgentEntity agentEntity;
		try {
			key = ((Set<String>) priceInfo.keySet()).iterator().next();
			priceInfo = priceInfo.getJSONObject(key);
			c = new CabinEntity();
			c.setProductName(productName);
			price = priceInfo.getDouble("pr");
			tax = priceInfo.getDouble("tax");
			c.setPrice(price);
			c.setTaxesPrice(tax);
			c.setOriginalPrice(price + tax);
			entity.getCabins().add(c);
			prices.add(new PriceCollect(price, tax, price + tax));
			if (priceInfo.get("wrid") != null && agentInfo.get(priceInfo.getString("wrid")) != null) {
				agentInfo = agentInfo.getJSONObject(priceInfo.getString("wrid"));
				if (agentInfo.getString("name").matches("^\\w*$")) {
					logger.info(String.format("代理商名称[%s]全英文,过滤", agentInfo.getString("name")));
				} else {
					String cname = agentInfo.getJSONObject("info").get("cname") == null ? agentInfo.getString("name") : agentInfo.getJSONObject("info").getString("cname");
					String addr = agentInfo.getJSONObject("info").get("addr") == null ? null : agentInfo.getJSONObject("info").getString("addr");
					agentEntity = PlaneInfoEntityBuilder.buildAgent(agentInfo.getString("name"), String.valueOf(price), null, getAgentTypeByCompanyName(cname), cname, addr, AgentEntity.class);
					agentEntity.setTaxesPrice(tax);
					agentEntity.setOriginalPrice(price + tax);
					entity.getAgents().add(agentEntity);
					/* entity.setAgentName(agentEntity.getName()); */
					logger.info(String.format("[%s]成功构建代理实体[%s][%s]", entity.getFlightNo(), agentEntity.getName(), agentEntity.getPrice()));
				}
			}
		} catch (Exception e) {

		} finally {
			c = null;
		}
	}

	/**
	 * 设置页面价格的仓位，见到的那个，从实体取出
	 */
	public void setPagePriceCabin(AbstractPlaneInfoEntity entity) {
		if (entity == null || entity.getTotalLowestPrice() == null) {
			return;
		}
		CabinEntity c;
		try {
			c = new CabinEntity();
			c.setProductName("最低报价(不含税)");
			c.setPrice(entity.getTotalLowestPrice());
			c.setTaxesPrice(entity.getTotalLowestTaxesPrice());
			c.setOriginalPrice(entity.getSumLowestPrice());
			if (entity instanceof SinglePlaneInfoEntity) {
				((SinglePlaneInfoEntity) entity).getCabins().add(c);
			} else if (entity instanceof DoublePlaneInfoEntity) {
				((DoublePlaneInfoEntity) entity).getCabins().add(c);
			}
		} catch (Exception e) {
			logger.error(e);
		} finally {
			c = null;
		}

	}

	/**
	 * 解析国际往返
	 * @deprecated 2014/8/21之后增加新类处理
	 * @param obj
	 * @return
	 * @throws Exception
	 */
	private List<Object> parseInterRound(Object obj) throws Exception {
		List<AbstractPlaneInfoEntity> result = new ArrayList<AbstractPlaneInfoEntity>();
		JSONObject r;
		JSONObject j;
		JSONObject m;
		JSONObject compInfo;// 公司对应关系json
		JSONObject flightInfo;// 航班组合对应关系
		JSONObject packagePriceInfo;
		JSONObject airportInfo;
		Map<String, String> depAryMap = new HashMap<String, String>();
		String key;
		Iterator<Entry<String, String>> it;
		Entry<String, String> en;
		String serverIP;
		String queryID;
		JSONObject transferInfo;
		try {
			r = (JSONObject) obj;
			j = r.getJSONObject("j");
			m = r.getJSONObject("m");
			logger.info("fetchFlag:" + fetchFlag);
			String dataKey = fetchFlag == normalFlag ? "rt_data" : "thunder_data";
			if(fetchFlag == normalFlag){
				compInfo = j.getJSONObject(dataKey).getJSONObject("carrierInfo");// 航空公司
				flightInfo = j.getJSONObject(dataKey).getJSONObject("flightInfo");// 去程或者回程的信息key:1TR2109/TR2986 0MU5740/MU741
				packagePriceInfo = j.getJSONObject(dataKey).getJSONObject("packagePriceInfo");
				transferInfo = j.getJSONObject(dataKey).getJSONObject("transferInfo");
				airportInfo = j.getJSONObject("airportInfo");
			}else{
				compInfo = m.getJSONObject(dataKey).getJSONObject("carrierInfo");// 航空公司
				flightInfo = m.getJSONObject(dataKey).getJSONObject("flightInfo");// 去程或者回程的信息key:1TR2109/TR2986 0MU5740/MU741
				packagePriceInfo = m.getJSONObject(dataKey).getJSONObject("packagePriceInfo");
				transferInfo = m.getJSONObject(dataKey).getJSONObject("transferInfo");
				airportInfo = m.getJSONObject(dataKey).getJSONObject("airportInfo");
			}
			serverIP = j.getString("serverIP");
			queryID = j.getString("queryID");
			// 简易取得航班信息
			// 0CX1234/CX1111|CA1234/CA4567/CA111
			// 0CX1234/CX113/CZ445|CA1234/CA4567/CA111
			// 虽然起飞的第一转相同，但是第二转不同，所以识别为两个entity,当|前完全一致的时候，认为是同去不同回

			for (Object o : packagePriceInfo.keySet()) {
				/* key = cpArray.getJSONObject(i).getString("key"); */
				key = o.toString();
				if (!depAryMap.containsKey(key.split("\\|")[0])) {
					depAryMap.put(key.split("\\|")[0], key.split("\\|")[1]);
				} else {
					depAryMap.put(key.split("\\|")[0], depAryMap.get(key.split("\\|")[0]) + "," + key.split("\\|")[1]);
				}
			}
			Map<String, Double> fcarrierPrice = new HashMap<String, Double>();
			if (j.get("inter_filters") != null && j.getJSONObject("inter_filters").get("fcarrier") != null) {// 这个里面有最低价格的航班
				JSONObject fcarrier = j.getJSONObject("inter_filters").getJSONObject("fcarrier");
				for (Object o1 : fcarrier.values()) {
					for (Object o2 : ((JSONObject) o1).values()) {
						JSONObject f = (JSONObject) o2;
						fcarrierPrice.put(f.getString("key"), f.getDouble("pr"));
						String f1 = f.getString("key").split("\\|")[0];
						String f2 = f.getString("key").split("\\|")[1];
						if (!depAryMap.containsKey(f1)) {
							depAryMap.put(f1, f2);
						} else if (depAryMap.get(f1).indexOf(f2) == -1) {
							depAryMap.put(f1, depAryMap.get(f1) + "," + f2);
						}
					}
				}
			}

			// 得到航班组合之后，开始切割数据
			it = depAryMap.entrySet().iterator();
			while (it.hasNext()) {
				JSONObject if1;
				JSONObject if2;
				DoublePlaneInfoEntity dPlaneInfoEntity;// 往返实体
				ReturnDoublePlaneInfoEntity rPlaneInfoEntity;// 回程实体
				en = it.next();
				/*
				 * if(en.getKey().indexOf("/")!=-1){ logger.info(String.format("去程[%s]非直达,过滤不解析", en.getKey())); continue; }
				 */
				if1 = flightInfo.getJSONObject(en.getKey());
				List<PriceCollect> prices = new ArrayList<PriceCollect>();
				try {
					dPlaneInfoEntity = (DoublePlaneInfoEntity) PlaneInfoEntityBuilder.buildPlaneInfo(taskQueue, if1.getString("ca"), compInfo.getJSONObject(if1.getString("ca")).getString("zh"),
							compInfo.getJSONObject(if1.getString("ca")).getString("full"), if1.getString("dt"), if1.getString("at") + "+" + (if1.getInt("cd") < 0 ? 0 : if1.getInt("cd")), // stb modify
																																															// 2014-06-11
																																															// 处理取得的跨天数为负数的情况
							en.getKey().replaceAll("^\\d", "").replaceAll("/.*", ""),// 航班号是截取第一个
							/*
							 * packagePriceInfo.getJSONObject(en.getKey() +"|"+rNos).getString("lowpr")
							 */null, null, /*
											 * packagePriceInfo. getJSONObject (en.getKey()+ "|"+rNos).getString ("lowpr")
											 */null, if1.getString("pt"));

					try {
						dPlaneInfoEntity.setFlightDuration(getLong(if1.getLong("dur")));
					} catch (Exception e) {
						//logger.info("增加国际往返总时间失败");
						//logger.info(if1);
						//logger.info(e);
					}
					// 经停
					addStopover(dPlaneInfoEntity, if1, en.getKey());

					if (en.getKey().indexOf("/") != -1) {// 去中转
						TransitEntity t;
						String[] arr = en.getKey().split("/");
						JSONArray tran = null;
						try {
							tran = transferInfo.getJSONArray(en.getKey().replaceAll("^0|^1", "").replaceAll("/[01]", "/"));
						} catch (Exception e) {
							//logger.info(en.getKey() + "获取中转信息失败");
							//logger.info(e);
						}
						for (int i = 0; i < arr.length; i++) {
							t = new TransitEntity();
							String no = arr[i];
							t.setFlightNo(no.replaceAll("^0|^1", ""));
							// 添加中转信息
							if (tran != null) {
								try {
									JSONObject lastObj = null;
									JSONObject thisObj = null;
									if (i == 0) {
										thisObj = tran.getJSONObject(i);
										t.setStartTime(PlaneInfoEntityBuilder.getFlightTime(taskQueue.getFlightDate(), if1.getString("dt")));
										t.setEndTime(PlaneInfoEntityBuilder.getFlightTime(taskQueue.getFlightDate(), thisObj.getString("at") + "+" + (thisObj.getInt("cd") < 0 ? 0 : thisObj.getInt("cd"))));
										t.setFromAirPort(if1.getString("da"));
										if(fetchFlag == moreFlag){
											t.setFromAirPortName(airportInfo.getJSONObject(if1.getString("da")).getString("ab"));
										}else{
											try {
												t.setFromAirPortName(airportInfo.getJSONObject("ret").getJSONObject(if1.getString("da")).getString("ab"));
											} catch (Exception e) {
												t.setFromAirPortName(airportInfo.getJSONObject("out").getJSONObject(if1.getString("da")).getString("ab"));
											}
										}
										t.setToAirPortName(thisObj.getJSONArray("ta").getString(0));
										t.setStayTime(getLong(thisObj.getLong("dur")));
									} else if (i == arr.length - 1) {
										lastObj = tran.getJSONObject(i - 1);
										t.setStartTime(PlaneInfoEntityBuilder.getFlightTime(taskQueue.getFlightDate(), lastObj.getString("dt") + "+" + (lastObj.getInt("cd") < 0 ? 0 : lastObj.getInt("cd"))));
										t.setEndTime(PlaneInfoEntityBuilder.getFlightTime(taskQueue.getFlightDate(), if1.getString("at") + "+" + (if1.getInt("cd") < 0 ? 0 : if1.getInt("cd"))));
										t.setFromAirPortName(lastObj.getJSONArray("ta").getString(1));
										t.setToAirPort(if1.getString("aa"));
										if(fetchFlag == moreFlag){
											t.setToAirPortName(airportInfo.getJSONObject(if1.getString("aa")).getString("ab"));
										}else{
											try {
												t.setToAirPortName(airportInfo.getJSONObject("ret").getJSONObject(if1.getString("aa")).getString("ab"));
											} catch (Exception e) {
												t.setToAirPortName(airportInfo.getJSONObject("out").getJSONObject(if1.getString("aa")).getString("ab"));
											}
										}
									} else {
										lastObj = tran.getJSONObject(i - 1);
										thisObj = tran.getJSONObject(i);
										t.setStartTime(PlaneInfoEntityBuilder.getFlightTime(taskQueue.getFlightDate(), lastObj.getString("dt") + "+" + (lastObj.getInt("cd") < 0 ? 0 : lastObj.getInt("cd"))));
										t.setToAirPortName(lastObj.getJSONArray("ta").getString(1));
										t.setEndTime(PlaneInfoEntityBuilder.getFlightTime(taskQueue.getFlightDate(), thisObj.getString("at") + "+" + (thisObj.getInt("cd") < 0 ? 0 : thisObj.getInt("cd"))));
										t.setToAirPortName(thisObj.getJSONArray("ta").getString(0));
										t.setStayTime(getLong(thisObj.getLong("dur")));
									}
								} catch (Exception e) {
									//logger.info(en.getKey() + "添加中转附加信息失败");
									//logger.info(e);
								}
							}
							dPlaneInfoEntity.getTransits().add(t);
						}
					}
					for (String rNos : en.getValue().split(",")) {// 切割回程航班
						// 组合分别找到出发和结束时间
						if2 = flightInfo.getJSONObject(rNos);
						// 回程如果也是中转，则用去的第一个构建ReturnDoublePlaneInfoEntity
						//FileUtil.writeString(getPrice(en.getKey() + "|" + rNos, packagePriceInfo) + "\n", true);
						rPlaneInfoEntity = PlaneInfoEntityBuilder.getReturnTrip(taskQueue, if2.getString("ca"), compInfo.getJSONObject(if2.getString("ca")).getString("zh"), compInfo.getJSONObject(if2.getString("ca")).getString("full"),
								if2.getString("dt"), if2.getString("at") + "+" + (if2.getInt("cd") < 0 ? 0 : if2.getInt("cd")), // stb modify 2014-06-11 处理取得的跨天数为负数的情况
								rNos.replaceAll("^\\d", "").replaceAll("/.*", ""), getPrice(en.getKey() + "|" + rNos, packagePriceInfo), null, getPrice(en.getKey() + "|" + rNos, packagePriceInfo), if2.getString("pt"));
						try{
							rPlaneInfoEntity.setFlightDuration(getLong(if2.getLong("dur")));
							JSONObject priceInfo = packagePriceInfo.getJSONObject(en.getKey()+"|"+rNos);
							Double pr = priceInfo.getDouble("lowpr");
							Double tax = priceInfo.getDouble("tax");
							Double sum = null;
							//总价跟随税价
							if(tax == null){
								sum = null;
							}else if(tax == 0){
								tax = null;
								sum = null;
							}else{
								sum = pr + tax;
							}
							rPlaneInfoEntity.setTotalHighestTaxesPrice(tax);
							rPlaneInfoEntity.setTotalLowestTaxesPrice(tax);
							rPlaneInfoEntity.setSumHighestPrice(sum);
							rPlaneInfoEntity.setSumLowestPrice(sum);
						}catch(Exception e){
							//logger.info("增加国际往返回程税费或总时间失败");
							//logger.info(if2);
							//logger.info(e);
						}
						// 14年7月，增加税费和合计价
						setEntityLowestPriceInfo(dPlaneInfoEntity, rPlaneInfoEntity.getTotalLowestPrice());
						setEntityHightPriceInfo(dPlaneInfoEntity, rPlaneInfoEntity.getTotalHighestPrice());
						String ke = en.getKey() + "|" + rNos;
						if (packagePriceInfo != null && ke != null) {
							JSONObject onePrice = packagePriceInfo.getJSONObject(ke);
							if (!isJSONObjectEmpty(onePrice)) {
								prices.add(new PriceCollect(onePrice.getDouble("lowpr"), onePrice.getDouble("tax"), onePrice.getDouble("lowpr") + onePrice.getDouble("tax")));
							} else {
								//logger.info(ke + " 设置价格失败");
							}
						}

						setPagePriceCabin(rPlaneInfoEntity);

						// 经停
						addStopover(rPlaneInfoEntity, if2, rNos);
						if (rNos.indexOf("/") != -1) {// 回中转
							String[] arr = rNos.split("/");
							JSONArray tran = null;
							try {
								tran = transferInfo.getJSONArray(rNos.replaceAll("^0|^1", "").replaceAll("/[01]", "/"));
							} catch (Exception e) {
								//logger.info(rNos + "获取回程中转信息失败");
								//logger.info(e);
							}
							ReturnTransitEntity t;
							for (int i = 0; i < arr.length; i++) {
								String no = arr[i];
								t = new ReturnTransitEntity();
								t.setFlightNo(no.replaceAll("^0|^1", ""));
								// 添加回程中转信息
								if (tran != null) {
									try {
										JSONObject lastObj = null;
										JSONObject thisObj = null;
										if (i == 0) {
											thisObj = tran.getJSONObject(i);
											t.setStartTime(PlaneInfoEntityBuilder.getFlightTime(taskQueue.getFlightDate(), if2.getString("dt")));
											t.setEndTime(PlaneInfoEntityBuilder.getFlightTime(taskQueue.getFlightDate(), thisObj.getString("at") + "+" + (thisObj.getInt("cd") < 0 ? 0 : thisObj.getInt("cd"))));
											t.setFromAirPort(if2.getString("da"));
											if(fetchFlag == moreFlag){
												t.setFromAirPortName(airportInfo.getJSONObject(if2.getString("da")).getString("ab"));
											}else{
												try {
													t.setFromAirPortName(airportInfo.getJSONObject("ret").getJSONObject(if2.getString("da")).getString("ab"));
												} catch (Exception e) {
													t.setFromAirPortName(airportInfo.getJSONObject("ret").getJSONObject("out").getJSONObject(if2.getString("da")).getString("ab"));
												}
											}
											t.setToAirPortName(thisObj.getJSONArray("ta").getString(0));
											t.setStayTime(getLong(thisObj.getLong("dur")));
										} else if (i == arr.length - 1) {
											lastObj = tran.getJSONObject(i - 1);
											t.setStartTime(PlaneInfoEntityBuilder.getFlightTime(taskQueue.getFlightDate(), lastObj.getString("dt") + "+" + (lastObj.getInt("cd") < 0 ? 0 : lastObj.getInt("cd"))));
											t.setEndTime(PlaneInfoEntityBuilder.getFlightTime(taskQueue.getFlightDate(), if2.getString("at") + "+" + (if2.getInt("cd") < 0 ? 0 : if2.getInt("cd"))));
											t.setFromAirPortName(lastObj.getJSONArray("ta").getString(1));
											t.setToAirPort(if2.getString("aa"));
											if(fetchFlag == moreFlag){
												t.setToAirPortName(airportInfo.getJSONObject(if2.getString("aa")).getString("ab"));
											}else{
												try {
													t.setToAirPortName(airportInfo.getJSONObject("ret").getJSONObject(if2.getString("aa")).getString("ab"));
												} catch (Exception e) {
													t.setToAirPortName(airportInfo.getJSONObject("out").getJSONObject(if2.getString("aa")).getString("ab"));
												}
											}
										} else {
											lastObj = tran.getJSONObject(i - 1);
											thisObj = tran.getJSONObject(i);
											t.setStartTime(PlaneInfoEntityBuilder.getFlightTime(taskQueue.getFlightDate(), lastObj.getString("dt") + "+" + (lastObj.getInt("cd") < 0 ? 0 : lastObj.getInt("cd"))));
											t.setToAirPortName(lastObj.getJSONArray("ta").getString(1));
											t.setEndTime(PlaneInfoEntityBuilder.getFlightTime(taskQueue.getFlightDate(), thisObj.getString("at") + "+" + (thisObj.getInt("cd") < 0 ? 0 : thisObj.getInt("cd"))));
											t.setToAirPortName(thisObj.getJSONArray("ta").getString(0));
											t.setStayTime(getLong(thisObj.getLong("dur")));
										}
									} catch (Exception e) {
										//logger.info(rNos + "添加回程中转附加信息失败");
										//logger.info(e);
									}
								}
								rPlaneInfoEntity.getReturnTransits().add(t);
							}

						}
						/*
						 * //分别找出对应的代理商，组合来回 String group=en.getKey()+"|"+rNos; setInterRoundAgents(packagePriceInfo,agentInfo,group,rPlaneInfoEntity);
						 */
						dPlaneInfoEntity.getReturnPlaneInfos().add(rPlaneInfoEntity);
					}

					if (returnFlag) {
						setDoublePlaneInfoEntityMoreAgent(dPlaneInfoEntity, prices, serverIP, queryID);
					}

					if (!prices.isEmpty()) {
						// dPlaneInfoEntity.setTotalLowestPrice(super.getPriceByType(prices, "lower"));
						// dPlaneInfoEntity.setTotalHighestPrice(super.getPriceByType(prices, "hight"));
						PriceCollect.buildPrice(dPlaneInfoEntity, prices);
					}
					
					result.add(dPlaneInfoEntity);
					/* showDirect(dPlaneInfoEntity); */
				} catch (Exception e) {
					logger.error(String.format("[%s]解析[%s] [%s]-[%s] [%s]-[%s] 详情[%s] 错误[%s]", super.taskQueue.getGrabChannel(), super.getRouteType().getName(), taskQueue.getFromCity(), taskQueue.getToCity(), taskQueue.getFlightDate(),
							taskQueue.getReturnGrabDate(), en.toString(), e));
				} finally {
					if1 = null;
					if2 = null;
					dPlaneInfoEntity = null;
				}

			}
		} finally {
			j = null;
			compInfo = null;// 公司对应关系json
			flightInfo = null;// 航班组合对应关系
			packagePriceInfo = null;
			depAryMap = null;
			key = null;
			it = null;
			en = null;
		}
		PlaneInfoCommon.removeNoPrice(result);
		return Arrays.asList(result.toArray());
	}
	
	/**
	 * 增加经停信息
	 * 
	 * @param entity
	 * @param flights
	 */
	public void addStopover(AbstractPlaneInfoEntity entity, JSONObject flight, String key) {
		try {
			String[] flightNos = key.split("/");
			String date = flight.getString("dd");
			JSONObject flights = flight.getJSONObject("flights");
			if (flights.isNullObject()) {
				return;
			}
			for (String no : flightNos) {
				String flightNo = no.replaceAll("^0|^1", "");
				JSONArray stops = flights.getJSONObject(flightNo).getJSONArray("stops");
				if (stops.isEmpty()) {
					continue;
				}
				for (int i = 0; i < stops.size(); i++) {
					JSONObject stop = stops.getJSONObject(i);
					if (entity instanceof SinglePlaneInfoEntity) {
						StopOverEntity stopOver = new StopOverEntity();
						stopOver.setArrTime(format.parse(date + " " + stop.getString("arrTime")));
						stopOver.setLeaveTime(format.parse(date + " " + stop.getString("depTime")));
						stopOver.setStayTime(formatTime(stop.getString("stopTime")));
						stopOver.setStopCity(stop.getString("stopCity"));
						stopOver.setFlightNo(flightNo);
						((SinglePlaneInfoEntity) entity).getStopOvers().add(stopOver);
					} else if (entity instanceof DoublePlaneInfoEntity) {
						StopOverEntity stopOver = new StopOverEntity();
						stopOver.setArrTime(format.parse(date + " " + stop.getString("arrTime")));
						stopOver.setLeaveTime(format.parse(date + " " + stop.getString("depTime")));
						stopOver.setStayTime(formatTime(stop.getString("stopTime")));
						stopOver.setStopCity(stop.getString("stopCity"));
						stopOver.setFlightNo(flightNo);
						((DoublePlaneInfoEntity) entity).getStopOvers().add(stopOver);
					} else if (entity instanceof ReturnDoublePlaneInfoEntity) {
						ReturnStopOverEntity stopOver = new ReturnStopOverEntity();
						stopOver.setArrTime(format.parse(date + " " + stop.getString("arrTime")));
						stopOver.setLeaveTime(format.parse(date + " " + stop.getString("depTime")));
						stopOver.setStayTime(formatTime(stop.getString("stopTime")));
						stopOver.setStopCity(stop.getString("stopCity"));
						stopOver.setFlightNo(flightNo);
						((ReturnDoublePlaneInfoEntity) entity).getReturnStopOvers().add(stopOver);
					}
				}
			}
		} catch (Exception e) {
			//logger.info("增加经停信息失败，key：" + key + ",flight:" + flight, e);
		}
	}

	/**
	 * 得到经停时间
	 * 
	 * @param time
	 * @return
	 */
	private static long formatTime(String time) {
		String hourStr = RegHtmlUtil.regStr(time, "(\\d+)小时");
		String minuteStr = RegHtmlUtil.regStr(time, "(\\d+)分钟");
		int hour = (hourStr == null ? 0 : Integer.valueOf(hourStr));
		int minute = (minuteStr == null ? 0 : Integer.valueOf(minuteStr));
		return (hour * 60 + minute) * 60 * 1000;
	}

	/**
	 * 展示直达的数据
	 * 
	 * @param entity
	 */
	private void showDirect(AbstractPlaneInfoEntity entity) {
		if (entity instanceof DoublePlaneInfoEntity) {
			if (((DoublePlaneInfoEntity) entity).getTransits().isEmpty()) {
				for (ReturnDoublePlaneInfoEntity reEntity : ((DoublePlaneInfoEntity) entity).getReturnPlaneInfos()) {
					if (reEntity.getReturnTransits().isEmpty()) {
						logger.info(String.format("[%s][%s][%s][%s][%s][%s]解析到直达航班[%s]-[%s]最低价[%s]最高价[%s]代理数量[%s]", taskQueue.getGrabChannel(), super.getRouteType().getName(), taskQueue.getFromCity(), taskQueue.getToCity(),
								taskQueue.getFlightDate(), taskQueue.getReturnGrabDate(), entity.getFlightNo(), reEntity.getFlightNo(), reEntity.getTotalLowestPrice(), reEntity.getTotalHighestPrice(), reEntity.getReturnAgents() == null ? 0
										: reEntity.getReturnAgents().size()));

					}
				}
			}
		} else if (entity instanceof SinglePlaneInfoEntity) {
			if (((SinglePlaneInfoEntity) entity).getTransits().isEmpty()) {
				logger.info(String.format("[%s][%s][%s][%s][%s]解析到直达航班[%s]最低价[%s]最高价[%s]代理数量[%s]", taskQueue.getGrabChannel(), super.getRouteType().getName(), taskQueue.getFromCity(), taskQueue.getToCity(), taskQueue.getFlightDate(),
						entity.getFlightNo(), entity.getTotalLowestPrice(), entity.getTotalHighestPrice(), ((SinglePlaneInfoEntity) entity).getAgents() == null ? 0 : ((SinglePlaneInfoEntity) entity).getAgents().size()));

			}
		}
	}

	/**
	 * 去、回是不是直达
	 * 
	 * @param entity
	 * @return
	 */
	private boolean isGoOrReturnDirect(AbstractPlaneInfoEntity entity) {
		if (entity instanceof SinglePlaneInfoEntity) {
			return entity == null ? false : (((SinglePlaneInfoEntity) entity).getTransits() == null || ((SinglePlaneInfoEntity) entity).getTransits().isEmpty()) ? true : false;
		} else if (entity instanceof DoublePlaneInfoEntity) {
			return entity == null ? false : (((DoublePlaneInfoEntity) entity).getTransits() == null || ((DoublePlaneInfoEntity) entity).getTransits().isEmpty()) ? true : false;
		} else if (entity instanceof ReturnDoublePlaneInfoEntity) {
			return entity == null ? false : (((ReturnDoublePlaneInfoEntity) entity).getReturnTransits() == null || ((ReturnDoublePlaneInfoEntity) entity).getReturnTransits().isEmpty()) ? true : false;
		} else {
			return false;
		}
	}

	private boolean isConformFlightNo(AbstractPlaneInfoEntity entity) {
		return entity == null ? false : entity.getFlightNo() == null ? false : airCompany.indexOf(entity.getFlightNo().substring(0, 2)) == -1 ? false : true;
	}

	// 获取价格的策略
	private String getPrice(String key, JSONObject packagePriceInfo) {
		if (packagePriceInfo == null || key == null) {
			return null;
		}
		if (packagePriceInfo.get(key) != null && packagePriceInfo.getJSONObject(key).get("lowpr") != null) {
			return packagePriceInfo.getJSONObject(key).getString("lowpr");
		}
		return null;
	}

	@SuppressWarnings("unused")
	private void setInterRoundAgents(JSONObject packagePriceInfo, JSONObject agentInfo, String group, AbstractPlaneInfoEntity entity) {

		try {
			if (isJSONObjectEmpty(packagePriceInfo) || isJSONObjectEmpty(agentInfo) || group == null || entity == null) {
				return;
			}
			String agentID = packagePriceInfo.getJSONObject(group).getString("lowprWrid");
			JSONObject agent = agentInfo.getJSONObject(agentID);
			String name = agent.getString("name");
			if (name != null) {// 放回代理名称
				entity.setAgentName(name);
			}
			String companyName = agent.getJSONObject("info").get("cname") == null ? null : agent.getJSONObject("info").getString("cname");
			String address = agent.getJSONObject("info").get("addr") == null ? null : agent.getJSONObject("info").getString("addr");
			if (entity instanceof DoublePlaneInfoEntity) {
				AgentEntity agentEntity = PlaneInfoEntityBuilder.buildAgent(name, null, null, 2, companyName, address, AgentEntity.class);
				agentEntity.setPrice(entity.getTotalLowestPrice());
				((DoublePlaneInfoEntity) entity).getAgents().add(agentEntity);/*
																			 * ((DoublePlaneInfoEntity)entity).setAgentName(agentEntity.getName());
																			 */
				/*
				 * logger.info(String.format("成功构建代理实体[%s][%s][%s][%s]",agentEntity.getName(),agentEntity.getCompanyName(),agentEntity.getAddress(),agentEntity.getPrice()));
				 */} else if (entity instanceof ReturnDoublePlaneInfoEntity) {
				ReturnAgentEntity agentEntity = PlaneInfoEntityBuilder.buildAgent(name, null, null, 2, companyName, address, ReturnAgentEntity.class);
				agentEntity.setPrice(entity.getTotalLowestPrice());
				((ReturnDoublePlaneInfoEntity) entity).getReturnAgents().add(agentEntity);/*
																						 * ((ReturnDoublePlaneInfoEntity)entity).setAgentName(agentEntity.getAgentName());
																						 */
				/*
				 * logger.info(String.format("成功构建代理实体[%s][%s][%s][%s]",agentEntity.getAgentName(),agentEntity.getCompanyName(),agentEntity.getAddress(),agentEntity.getPrice()));
				 */}
		} catch (Exception e) {

		} finally {

		}
	}

	public boolean isJSONObjectEmpty(JSONObject j) {
		if (j == null || j.isNullObject() || j.isEmpty()) {
			return true;
		} else {
			return false;
		}
	}
	
	/**
	 * 替换掉一个城市机场里面具体机场的名字，都是用城市来查的
	 * @param cityName
	 * @return
	 */
	public  String getCity(String cityName){
		return cityName.replaceAll("\\(.*\\)", "").replaceAll("（.*）", "");
	}
	
	/**
	 * 按分钟数返回毫秒数
	 * 
	 * @param minute
	 * @return
	 */
	public Long getLong(Long minute) {
		if (minute == null) {
			return null;
		}
		return minute * 60 * 1000;
	}

	@Override
	public String getUrl() throws Exception {
		// TODO Auto-generated method stub
		return null;
	}
	
	public void setEntityLowestPriceInfo(AbstractPlaneInfoEntity entity, Double price) {
		if (entity == null || price == null) {
			return;
		}
		entity.setTotalLowestPrice(entity.getTotalLowestPrice() == null ? price : Math.min(entity.getTotalLowestPrice(), price));
	}

	public void setEntityHightPriceInfo(AbstractPlaneInfoEntity entity, Double price) {
		if (entity == null || price == null) {
			return;
		}
		entity.setTotalHighestPrice(entity.getTotalHighestPrice() == null ? price : Math.max(entity.getTotalHighestPrice(), price));
	}

	public static void main(String[] args) throws Exception {
		TaskModel taskModel = new TaskModel();
		taskModel.setFromCity("CKG");
		// taskModel.setFromCityName("通辽");
		taskModel.setFromCityName("重庆");
		taskModel.setToCity("KHN");
		// taskModel.setToCityName("上海");
		taskModel.setToCityName("南昌");
		taskModel.setFlightDate("2014-12-20");
		taskModel.setIsReturn(0);
		taskModel.setIsInternational(0);
		taskModel.setReturnGrabDate("2014-12-26");
		QunarAdapter adapter = new QunarAdapter(taskModel);
		/*
		 * File file = new File("C:/Users/like/Desktop/test.txt"); FileReader reader = new FileReader(file); BufferedReader bufferReader = new BufferedReader(reader); String s; String ap = "";
		 * while((s = bufferReader.readLine()) != null){ ap += s; } JSONObject flight = JSONObject.fromObject(ap); adapter.addStopover(new DoublePlaneInfoEntity(), flight, "1AA2928/AA153/CA422");
		 */
		Object ob = adapter.fetch(null);
		List<Object> objList = adapter.paraseToVo(ob);
		System.out.println(objList);
		// Object obj = objList.get(0);
		// AbstractPlaneInfoEntity en = (obj instanceof SinglePlaneInfoEntity)?(SinglePlaneInfoEntity)obj:(DoublePlaneInfoEntity) obj;
		// JSONObject json = JSONObject.fromObject(en);
		// System.out.println(json.toString());
	}
	
	/**
	 * 解密QueryID
	 * @param queryId
	 * @return
	 */
	private String unQueryID(String queryId){
		int k= queryId.indexOf(':');
		String address=queryId.substring(0, k + 1);
		
		String str = queryId.substring(k + 1) ;
		StringBuilder build=new StringBuilder();
		for(int i=0;i<str.length();i++){
			char c=str.charAt(i);
			int unicode=c;
			unicode--;
			c=(char) unicode;
			build.append(c);
		}
		build.reverse();
		return address+build.toString();
	}
	
}
